﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Linq;
using System.Text;
using System.Web;
using Medianamik.Core.Security;
using System.Security.Permissions;
using System.Web.Security;
using Medianamik.Core;
using System.Globalization;
using System.Threading;
using Medianamik.Core.Configuration;
using System.Configuration;
using Medianamik.Core.Profile;
using Medianamik.Core.Logging;

namespace Medianamik.Core
{
    public sealed class MedianamikContext
    {
        private const string USER_KEY = "MedianamikContext_CurrentUser";
        private const string EDITION_CULTURE_KEY = "MedianamikContext_CurrentEditionCulture";

        private static readonly MedianamikConfigSection _config = (MedianamikConfigSection)ConfigurationManager.GetSection(ConfigurationSectionName.MEDIANAMIK);

        public MedianamikContext()
        {

        }

        public static MedianamikContext Current
        {
            get
            {
                //Singleton necessaire ?
                return Singleton<MedianamikContext>.Instance;

            }
        }

        public MedianamikUser MedianamikUser
        {
            get
            {
                if (HttpContext.Current == null)
                {
                    throw new CoreException("HttpContext.Current cannot be 'null'. This property is only accessible through HttpContext.Current");
                }
                return HttpContext.Current.Session[USER_KEY] as MedianamikUser
                    ?? ((MedianamikUser)(HttpContext.Current.Session[USER_KEY] = (MedianamikUser)Membership.GetUser()));
            }
        }

        public CultureInfo EditionCulture
        {
            get
            {
                //FIXME : Bug potentiel si l'usager utilise deux fenetres et change la culture dans une.
                if (HttpContext.Current == null)
                {
                    //throw new CoreException("HttpContext.Current cannot be 'null'. This property is only accessible through HttpContext.Current");
                    //PL : Plutôt que de faire plenter l'application, on envoi la culture d'édition par défaut.
                    return CultureInfo.GetCultureInfo(_config.DefaultEditionCultureName);
                }

                var culture = HttpContext.Current.Items[EDITION_CULTURE_KEY] as CultureInfo;

                if (culture == null)
                {
                    var cookie = HttpContext.Current.Request.Cookies[CookieName.CULTURE_COOKIE];

                    try
                    {
                        culture = CultureInfo.GetCultureInfo(cookie.Value);
                    }
                    catch
                    {
                        culture = DefaultCulture;
                        cookie = new HttpCookie(CookieName.CULTURE_COOKIE, culture.Name);
                        HttpContext.Current.Response.Cookies.Add(cookie);
                    }

                    //Correction: ne pas permettre une langue non disponible
                    var editionCultures = ConfigManager.GetEditionCultures().ToList();
                    if (!editionCultures.Any(c => c.CultureInfo.Equals(culture)))
                    {
                        culture = editionCultures.Any(c => c.CultureInfo.Equals(DefaultCulture)) ? 
                            DefaultCulture : editionCultures.Select(c => c.CultureInfo).First();
                        cookie = new HttpCookie(CookieName.CULTURE_COOKIE, culture.Name);
                        HttpContext.Current.Response.Cookies.Add(cookie);
                    }

                    HttpContext.Current.Items[EDITION_CULTURE_KEY] = culture;
                }

                return culture;
            }
            set
            {
                if (value == null) { throw new ArgumentNullException("EditionCulture"); }

                var cookie = new HttpCookie(CookieName.CULTURE_COOKIE, value.Name);
                HttpContext.Current.Response.Cookies.Add(cookie);
                HttpContext.Current.Items[EDITION_CULTURE_KEY] = value;
            }
        }

        private CultureInfo _defaultCulture;
        public CultureInfo DefaultCulture
        {
            get {
                return _defaultCulture ?? (_defaultCulture = 
                    CultureInfo.GetCultureInfo(_config.DefaultEditionCultureName));
            }
        }

        public CultureInfo CurrentUICulture { get { return System.Threading.Thread.CurrentThread.CurrentUICulture; } }

        public bool LockingIsEnabled
        {
            get
            {
                return _config.EnableLock;
            }
        }

        public UserProfile Profile
        {
            get { return HttpContext.Current.Profile as UserProfile; }
        }
    }
}
